package com.hk.core.autoconfigure.data.sharding;

import org.springframework.boot.ConfigurableBootstrapContext;
import org.springframework.boot.SpringApplicationRunListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.util.ClassUtils;

import java.time.Duration;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;

/**
 * @author Kevin
 * @date 2024-07-03 17:59
 */
public class ShardingSpringApplicationRunListener implements SpringApplicationRunListener {

    private final Set<String> propKeys = new HashSet<>();

    @Override
    public void environmentPrepared(ConfigurableBootstrapContext bootstrapContext, ConfigurableEnvironment environment) {
        if (ClassUtils.isPresent("com.hk.core.sharding.DataSourceName", null)) {
            String profiles = environment.getActiveProfiles()[0];
            System.out.println(STR."------> environmentPrepared: \{profiles}");
            Properties properties = System.getProperties();
            /*
              在 sharding.yaml 配置文件中，设置密码加密，这里加入到系统 属性中解密
               还需要在 spring.datasource.url 中加入 ?placeholder-type=SYSTEM_PROPS， 指定从哪里获取数据，如这里配置为系统属性: SYSTEM_PROPS
              源码参考:
             * org.apache.shardingsphere.infra.url.core.arg.URLArgumentLineRender#render(java.util.Collection, org.apache.shardingsphere.infra.url.core.arg.URLArgumentPlaceholderType)
             * org.apache.shardingsphere.infra.url.core.arg.URLArgumentLine#replaceArgument(org.apache.shardingsphere.infra.url.core.arg.URLArgumentPlaceholderType)
             */
            properties.put("ds_0_password", "password: root");
            properties.put("ds_1_password", "password: root");
            propKeys.add("ds_0_password");
            propKeys.add("ds_1_password");
        }
    }

    @Override
    public void ready(ConfigurableApplicationContext context, Duration timeTaken) {
        Properties properties = System.getProperties();
        propKeys.forEach(properties::remove);
        propKeys.clear();
    }
}
